package de.gwtprime.server.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

import org.apache.log4j.Logger;

import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;

import de.gwtprime.server.sql.helper.HibernateHelper;


@Entity
@Table(name = "users2")
public class User2 extends EntityBase {

	
	/**
	 * Serial ID
	 */
	private static final long serialVersionUID = 1L;

	@Column(unique=true)
	private String email;

	private boolean isAdmin;
	
	private String name;
	
	/**
	 * The karma can be increased by "good" actions like good questions, answers...
	 * The more karma a user has, the more privileges he gains
	 */
	private Long karma;

	/**
	 * Logger
	 */
	private static Logger logger = Logger.getLogger(User2.class);


	/**
	 * Default constructor for JPA
	 */
	public User2(){}
	public User2(String name){
		this.setName(name);
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}



	public Long persist(){
		return HibernateHelper.persist(this);
	}

	public void remove(){

		HibernateHelper.remove(this);

	}

	public static User2 findUser2(Long id) {
		return HibernateHelper.find(User2.class, id);
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}


	/**
	 * First check in the session: If there no user is the session context yet -> check the DB.
	 * @param email
	 * @return
	 */
	public static User2 findUserByEmail(String email){

		logger.info("Getting user by email: "+email);
		
		User2 userFromSession = findUserInSession();

		if(userFromSession!=null)
			return userFromSession;

		logger.info(String.format("No user was found in the session. Looking up in the DB the user '%s'", email));
		String query = String.format("from %s where email='%s'", User2.class.getName(), email);


		User2 user = (User2)HibernateHelper.queryDB(new User2(), query);
		
		logger.info(String.format("User looked up in the DB: '%s', id: %s", user == null ? "no user found" : user.getEmail(), user == null ? "-" : user.getId()));
		
		if(RequestFactoryServlet.getThreadLocalRequest()!=null){
			RequestFactoryServlet.getThreadLocalRequest().getSession().setAttribute("user", user);
		}
		return user;
	}
	public static User2 findUserInSession() {
		logger.info("Looking up the user in the session");
		logger.info("RequestFactoryServlet.getThreadLocalRequest(): " +RequestFactoryServlet.getThreadLocalRequest());
		
		if(RequestFactoryServlet.getThreadLocalRequest()!=null)
		
		if(RequestFactoryServlet.getThreadLocalRequest()!=null){
			
			Object userObj = RequestFactoryServlet.getThreadLocalRequest().getSession().getAttribute("user");
			if(userObj!=null){
				User2 user = (User2)userObj;
				logger.info(String.format("Found user '%s' in the session, user-id: %s", user.getEmail(), user.getId()));
				return user;
				
			}
		}
		
		logger.info("No user found in the session");
		
		return null;
	}
	public boolean isAdmin() {
		return isAdmin;
	}
	public void setAdmin(boolean isAdmin) {
		this.isAdmin = isAdmin;
	}
	
	@Override
	public String toString() {
		return String.format("E-mail: %s, id: %s", getEmail(), getId());
	}
	public Long getKarma() {
		return karma;
	}
	public void setKarma(Long karma) {
		this.karma = karma;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		User2 other = (User2) obj;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		return true;
	}
	
	/**
	 * Increase/Decrease Karma and persist user
	 */
	public void changeKarma(long karma){
		if(this.karma == null){
			this.karma = karma;
		}else{
			this.karma = this.karma + karma;
		}
		
		persist();
	}


}